package com.ytjj.qmyx.mall.amqp.consumer;

import com.rabbitmq.client.Channel;
import com.ytjj.common.constants.QueueConstants;
import com.ytjj.common.dto.mqdto.SellAfterDto;
import com.ytjj.qmyx.mall.enums.MQFailLogStatusEnums;
import com.ytjj.qmyx.mall.enums.MQFailLogTypeEnums;
import com.ytjj.qmyx.mall.model.MqFailLog;
import com.ytjj.qmyx.mall.service.MqFailLogService;
import com.ytjj.qmyx.mall.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;

/**
 *
 *  *
 **/
@Component
@Slf4j
public class SellAfterListener {

    @Resource
    private ProductService productService;
    @Autowired
    private MqFailLogService mqFailLogService;

//    @Transactional(rollbackFor = Exception.class)
    @RabbitListener(queuesToDeclare = @Queue(value = QueueConstants.SELL_AFTER_QUEUE, durable = "true"), concurrency = "4-8")
    public void sellAfter(SellAfterDto sellAfterDto, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws Exception {
        log.info("\n\n收到一条消费后消息：" + sellAfterDto+"\n\n");
        try {
            productService.sellAfterOld(sellAfterDto.getProductId(),sellAfterDto.getProductSpecId(),sellAfterDto.getSum(),sellAfterDto.getProductPrice(), sellAfterDto.getIsWalletPay(),
                    sellAfterDto.getIsDirectbuy(),sellAfterDto.getActivityType(),sellAfterDto.getActivityMax(),sellAfterDto.getUserId());
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            log.error("===QueueConstants.SELL_AFTER_QUEUE消费失败," + sellAfterDto);
            MqFailLog mqFailLog = generateObj(null == sellAfterDto ? "" : sellAfterDto.toString(), "业务异常", QueueConstants.SELL_AFTER_QUEUE);
            int count = mqFailLogService.insert(mqFailLog);
            if (count <= 0) {
                log.error("消息记录数据库失败SellAfterListener.sellAfter:" + sellAfterDto);
            }
            channel.basicReject(deliveryTag, false);
        }

    }

//    @Transactional(rollbackFor = Exception.class)
    @RabbitListener(queuesToDeclare = @Queue(value = QueueConstants.SELL_AFTER_QUEUE_ONE, durable = "true"), concurrency = "4-8")
    public void sellAfter1(SellAfterDto sellAfterDto, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws IOException {
        log.info("\n\n收到一条消费后消息：" + sellAfterDto+"\n\n");
        try {
            productService.sellAfterOld(sellAfterDto.getProductId(),sellAfterDto.getProductSpecId(),sellAfterDto.getSum(),sellAfterDto.getProductPrice(), sellAfterDto.getIsWalletPay(),
                    sellAfterDto.getTokenUsers(),sellAfterDto.getIsDirectbuy(),sellAfterDto.getActivityType(),sellAfterDto.getActivityMax(),sellAfterDto.getUserId());
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            log.info("===QueueConstants.SELL_AFTER_QUEUE_ONE消费失败,{},{}",sellAfterDto, e);
            MqFailLog mqFailLog = generateObj(null == sellAfterDto ? "" : sellAfterDto.toString(), "业务异常", QueueConstants.SELL_AFTER_QUEUE_ONE);
            int count = mqFailLogService.insert(mqFailLog);
            if (count <= 0) {
                log.error("消息记录数据库失败SellAfterListener.sellAfter1:" + sellAfterDto);
            }
            channel.basicReject(deliveryTag, false);
        }
    }

    private MqFailLog generateObj(String message, String reason, String queue) {
        MqFailLog mqFailLog = MqFailLog.builder()
                .type(MQFailLogTypeEnums.CONSUMER.getValue())
                .message(message)
                .createTime(new Date())
                .reason(reason)
                .queue(queue)
                .status(MQFailLogStatusEnums.WAIT.getValue())
                .build();
        return mqFailLog;
    }
}
